package com.cinema.dao.impl;

import com.cinema.dao.MovieDao;
import com.cinema.model.Movie;
import com.cinema.util.SimpleFileUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 电影数据访问实现类
 */
public class MovieDaoImpl implements MovieDao {
    private static final String MOVIE_DATA_FILE = "movies.txt";
    private List<Movie> movies;

    public MovieDaoImpl() {
        loadMovies();
    }

    private void loadMovies() {
        movies = new ArrayList<>();
        List<String> lines = SimpleFileUtil.readLines(MOVIE_DATA_FILE);
        for (String line : lines) {
            if (line.trim().isEmpty()) continue;
            Movie movie = parseMovieFromLine(line);
            if (movie != null) {
                movies.add(movie);
            }
        }
    }

    private void saveMovies() {
        List<String> lines = new ArrayList<>();
        for (Movie movie : movies) {
            lines.add(movieToLine(movie));
        }
        SimpleFileUtil.writeLines(MOVIE_DATA_FILE, lines);
    }

    private Movie parseMovieFromLine(String line) {
        try {
            String[] parts = line.split("\\|");
            if (parts.length >= 7) {
                Movie movie = new Movie();
                movie.setMovieId(parts[0]);
                movie.setTitle(parts[1]);
                movie.setDirector(parts[2]);
                movie.setActors(parts[3]);
                movie.setPlot(parts[4]);
                movie.setDuration(Integer.parseInt(parts[5]));
                movie.setShowing(Boolean.parseBoolean(parts[6]));
                if (parts.length > 7) {
                    movie.setRating(Double.parseDouble(parts[7]));
                }
                return movie;
            }
        } catch (Exception e) {
            // 跳过无效行
        }
        return null;
    }

    private String movieToLine(Movie movie) {
        return movie.getMovieId() + "|" + 
               movie.getTitle() + "|" + 
               movie.getDirector() + "|" + 
               movie.getActors() + "|" + 
               movie.getPlot() + "|" + 
               movie.getDuration() + "|" + 
               movie.isShowing() + "|" + 
               movie.getRating();
    }

    @Override
    public boolean save(Movie movie) {
        if (movie == null || existsById(movie.getMovieId())) {
            return false;
        }
        
        movies.add(movie);
        saveMovies();
        return true;
    }

    @Override
    public Optional<Movie> findById(String movieId) {
        return movies.stream()
                .filter(movie -> movieId.equals(movie.getMovieId()))
                .findFirst();
    }

    @Override
    public Optional<Movie> findByTitle(String title) {
        return movies.stream()
                .filter(movie -> title.equals(movie.getTitle()))
                .findFirst();
    }

    @Override
    public List<Movie> findAll() {
        return new ArrayList<>(movies);
    }

    @Override
    public List<Movie> findAllShowing() {
        return movies.stream()
                .filter(Movie::isShowing)
                .collect(Collectors.toList());
    }

    @Override
    public List<Movie> findByDirector(String director) {
        return movies.stream()
                .filter(movie -> movie.getDirector().contains(director))
                .collect(Collectors.toList());
    }

    @Override
    public List<Movie> findByActor(String actor) {
        return movies.stream()
                .filter(movie -> movie.getActors().contains(actor))
                .collect(Collectors.toList());
    }

    @Override
    public List<Movie> findByTitleDirectorActor(String title, String director, String actor) {
        return movies.stream()
                .filter(movie -> {
                    boolean matchTitle = title == null || title.isEmpty() || movie.getTitle().contains(title);
                    boolean matchDirector = director == null || director.isEmpty() || movie.getDirector().contains(director);
                    boolean matchActor = actor == null || actor.isEmpty() || movie.getActors().contains(actor);
                    return matchTitle && matchDirector && matchActor;
                })
                .collect(Collectors.toList());
    }

    @Override
    public boolean update(Movie movie) {
        if (movie == null) {
            return false;
        }
        
        for (int i = 0; i < movies.size(); i++) {
            if (movie.getMovieId().equals(movies.get(i).getMovieId())) {
                movies.set(i, movie);
                saveMovies();
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean deleteById(String movieId) {
        boolean removed = movies.removeIf(movie -> movieId.equals(movie.getMovieId()));
        if (removed) {
            saveMovies();
        }
        return removed;
    }

    @Override
    public boolean existsById(String movieId) {
        return movies.stream()
                .anyMatch(movie -> movieId.equals(movie.getMovieId()));
    }
}